﻿#include "PlatformProperty.h"

// 《DHU8_SWRA_FuncSpec_Vehicle-外灯设置.pdf》
//  3.2.9 [SW_FC_056_010]Vehicle外灯_后雾灯RearFogLight(原生)
// 上一次usgmode
static sdb::UsgModSts1 lastUsgMode = sdb::UsgModSts1::UsgModAbdnd;

static int32_t lightControlValue;  // 大灯类型
static PropertyStatus getFogLightSwitchStatus() {
    uint32_t afc = lcfg::LocalConfig::getInstance().getInt<int32_t>(lcfg::LCFG_ReFogLi_SoftSwt_Btn);
    auto usgMod = SIGNAL.getVehModMngtGlbSafe1UsgModSts();
    bool isAbdndChanged = sdb::UsgModSts1::UsgModAbdnd == usgMod && lastUsgMode != usgMod;
    lastUsgMode = usgMod;
    if (isAbdndChanged) {
        SIGNAL.setFogSetRearReq(sdb::OnOffNoReq::Off);
    }
    if (afc != 1) {
        VHALOG.d("FOG_LIGHTS_SWITCH: not available, afc:%u", afc);
        return PropertyStatus::NotAvailable;
    }
    sdb::LiExtFctReq1 li2 = SIGNAL.getSwtExtrLi2LiExtFctReq1();
    sdb::LiExtFctReq1 li3 = SIGNAL.getSwtExtrLi3LiExtFctReq1();

    auto usgmod = SIGNAL.getVehModMngtGlbSafe1UsgModSts();
    auto carmod = SIGNAL.getVehModMngtGlbSafe1CarModSts1();
    auto cc13 = SIGNAL.getcarconfig13();
    VHALOG.d(
        "FOG_LIGHTS_SWITCH: li2:%d,li3:%d, lightControlValue:%d, afc:%u, usgmod:%d, "
        "carmod:%d, cc13:%d",
        static_cast<int32_t>(li2), static_cast<int32_t>(li3), lightControlValue, afc, usgmod,
        carmod, cc13);

    bool usgModeIsOK = ((SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc) &&
                         SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_04)) ||
                        SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModActv, sdb::UsgModSts1::UsgModDrvg));

    bool extFctReqIsOk =
        (li2 != sdb::LiExtFctReq1::Off && li2 != sdb::LiExtFctReq1::Pos) ||
        (li3 != sdb::LiExtFctReq1::Off && li3 != sdb::LiExtFctReq1::Pos) ||
        (lightControlValue !=
             static_cast<int32_t>(ExteriorLightControlValue::LAMP_EXTERIOR_LIGHT_CONTROL_OFF) &&
         lightControlValue !=
             static_cast<int32_t>(ExteriorLightControlValue::LAMP_EXTERIOR_LIGHT_CONTROL_POS_LIGHT));

    if (SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModCrash,
                         sdb::CarModSts1::CarModDyno) &&
        usgModeIsOK && extFctReqIsOk) {
        return PropertyStatus::Active;
    } else {
        return PropertyStatus::NotActive;
    }
}

SYSTEM_READ_WRITE_PROPERTY(FOG_LIGHTS_SWITCH, int32_t) {
    builder.area(VehicleArea::GLOBAL)
        .initValue([]() {
            if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
                VHALOG.d("initValue FOG_LIGHTS_SWITCH : setCB_VFC_SetVehMisc");
                SIGNAL.setCB_VFC_SetVehMisc(sdb::OnOff1::On);
            }
            SIGNAL.setFogSetRearReq(sdb::OnOffNoReq::Off);

            return static_cast<int32_t>(VehicleLightSwitch::OFF);
        })
        .withStatusBySignals(
            []([[maybe_unused]] PropertyStatus last) { return getFogLightSwitchStatus(); },
            SignalRX::VehModMngtGlbSafe1UsgModSts, SignalRX::VehModMngtGlbSafe1CarModSts1,
            SignalRX::SwtExtrLi2LiExtFctReq1, SignalRX::SwtExtrLi3LiExtFctReq1)
        .withValueBySignals(
            []([[maybe_unused]] const int32_t& last) {
                sdb::DevSts4 devSts4 = SIGNAL.getExtrLtgStsReFog();
                VHALOG.d("HalWithValueBySignals FOG_LIGHTS_SWITCH last[%d] cur[%d]", last, devSts4);

                sdb::Timeout reFogTimeout = SIGNAL.getExtrLtgStsTimeout();
                if (reFogTimeout == sdb::Timeout::Timeout) {
                    VHALOG.d("HalWithValueBySignals FOG_LIGHTS_SWITCH: timeout");
                    return last;
                }

                bool isSendSignal = false;
                sdb::OnOffNoReq signalValue;
                if ((last == static_cast<int32_t>(VehicleLightSwitch::OFF)) &&
                    (devSts4 == sdb::DevSts4::On)) {
                    isSendSignal = true;
                    signalValue = sdb::OnOffNoReq::On;
                } else if ((last == static_cast<int32_t>(VehicleLightSwitch::ON)) &&
                           (devSts4 == sdb::DevSts4::Off)) {
                    isSendSignal = true;
                    signalValue = sdb::OnOffNoReq::Off;
                }
                if (isSendSignal) {
                    if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
                        VHALOG.d(
                            "HalWithValueBySignals FOG_LIGHTS_SWITCH : "
                            "setCB_VFC_SetVehMisc");
                        SIGNAL.setCB_VFC_SetVehMisc(sdb::OnOff1::On);
                    }
                    SIGNAL.setFogSetRearReq(signalValue);
                }

                return devSts4 == sdb::DevSts4::On ? static_cast<int32_t>(VehicleLightSwitch::ON)
                                                   : static_cast<int32_t>(VehicleLightSwitch::OFF);
            },
            SignalRX::ExtrLtgStsReFog, SignalRX::ExtrLtgStsTimeout)
        .onSetProperty([](const int32_t& value) {
            if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
                VHALOG.d("HalOnSetProperty FOG_LIGHTS_SWITCH : setCB_VFC_SetVehMisc");
                SIGNAL.setCB_VFC_SetVehMisc(sdb::OnOff1::On);
            }
            SIGNAL.setFogSetRearReq((value == static_cast<int32_t>(VehicleLightSwitch::ON))
                                        ? sdb::OnOffNoReq::On
                                        : sdb::OnOffNoReq::Off);
        })
        .onPropertyValueChange(
            ECarXVehicleProperty::SETTING_FUNC_LAMP_EXTERIOR_LIGHT_CONTROL, VehicleArea::GLOBAL,
            [this](const VehiclePropValue& propvalue) {
                VHALOG.d(
                    "onPropertyValueChange FOG_LIGHTS_SWITCH "
                    ": SETTING_FUNC_LAMP_EXTERIOR_LIGHT_CONTROL");
                lightControlValue = getPropertyValue<int32_t>(
                    static_cast<int32_t>(
                        ECarXVehicleProperty::SETTING_FUNC_LAMP_EXTERIOR_LIGHT_CONTROL),
                    static_cast<int32_t>(VehicleArea::GLOBAL));
                updateAreaStatus(static_cast<int32_t>(VehicleArea::GLOBAL),
                                 getFogLightSwitchStatus());
            });
}
